﻿using System.Collections.Generic;
using System.IO;
using System.Text;
using RpcHelper;

namespace CLIHelper.Model
{
    internal class GatewayApiBody
    {
        public ApiBody _body;
        private readonly ApiServiceBody _service;
        private string _Prefix;
        public GatewayApiBody(ApiBody body, ApiServiceBody service)
        {
            this._service = service;
            this._body = body;
            string root = this._service.Root.ToLower();
            if (root.EndsWith("service"))
            {
                root=root.Substring(0, root.Length - 7);
            }
            _Prefix = string.Concat(root, ".", this._service.RootName.ToLower());
        }
        private string _ModelName;
        private List<string> _Use = new List<string>();

        public List<string> Use => this._Use;

        public void WriteMethod(StringBuilder str)
        {
            StringBuilder arg = new StringBuilder();
            int mode = 2;
            if (!this._ModelName.IsNull())
            {
                mode = 0;
                arg.AppendFormat("[NullValidate(\"{1}.param.null\")]{0} param", this._ModelName,_Prefix);
            }
            else if (_body.Params.Length > 0)
            {
                _body.Params.ForEach(c =>
               {
                   if (c.ParamType == "basic")
                   {
                       arg.AppendFormat("{1}{0},", c.ToString(), c.GetValidate(_Prefix));
                   }
               });
                if (arg[arg.Length - 1] == ',')
                {
                    mode = 1;
                    arg.Remove(arg.Length - 1, 1);
                }
            }
            string name = this._body.ApiName.Replace(this._service.RootName, string.Empty);
            Helper.Helper.WriteApiShow(_body, mode, str);
            str.Append("\t\t");
            if (this._body.IsPaging)
            {
                str.AppendFormat("public PagingResult<{0}> {1}({2})\r\n", Helper.Helper.FormatTypeName(this._body.Return.Type), name, arg.ToString());
            }
            else
            {
                str.AppendFormat("public {0} {1}({2})\r\n", this._body.Return.ToString(), name, arg.ToString());
            }
            str.AppendLine("\t\t{");
            str.Append("\t\t\t");
            if (this._body.IsPaging)
            {
                string rName = Helper.Helper.FormatTypeName(this._body.Return.Type);
                str.AppendFormat(" {0}[] results = this._Service.{1}(", rName, this._body.ApiName);
                this._body.Params.ForEach(a =>
                {
                    if (a.Name == "count")
                    {
                        str.Append("out int " + a.Name);
                        str.Append(",");
                    }
                    else if (a.ParamType == "paging")
                    {
                        str.Append("param,");
                    }
                    else if (mode == 1)
                    {
                        str.Append(a.Name);
                        str.Append(",");
                    }
                    else
                    {
                        str.AppendFormat("param.{0},", a.SourceProName);
                    }
                }); 
                str.Remove(str.Length - 1, 1);
                str.AppendLine(");");
                str.AppendFormat("\t\t return new PagingResult<{0}>(count, results);\r\n", rName);
            }
            else
            {
                if (this._body.Return.Type != ConstDic._VoidType)
                {
                    str.Append("return ");
                }
                str.AppendFormat("this._Service.{0}", this._body.ApiName);
                if (arg.Length == 0)
                {
                    str.AppendLine("();");
                }
                else
                {
                    str.Append("(");
                    this._body.Params.ForEach(a =>
                    {
                        if (mode == 1)
                        {
                            str.Append(a.Name);
                            str.Append(",");
                        }
                        else
                        {
                            str.AppendFormat("param.{0},", a.SourceProName);
                        }
                    });
                    str.Remove(str.Length - 1, 1);
                    str.AppendLine(");");
                }
            }
            str.AppendLine("\t\t}");

        }
        private string CreateUi_Model()
        {
            StringBuilder str = new StringBuilder();
            this._body.UseList.ForEach(a =>
            {
                str.AppendFormat("using {0};\r\n", a);
            });
            str.Append("using RpcHelper.Validate;");
            str.AppendLine();
            string use = string.Concat(this._service.Namespace, ".Model.", this._service.RootName);
            this._Use.Add(use);
            str.AppendFormat("namespace {0}\r\n", use);
            str.AppendLine("{");
            this._ModelName = string.Concat("UI_", this._body.ApiName);
            Helper.Helper.WriteUiShow(this._body, str);
            if (this._body.IsPaging)
            {
                str.AppendFormat("\tinternal class {0} : BasicPage\r\n", this._ModelName);
            }
            else
            {
                str.AppendFormat("\tinternal class {0}\r\n", this._ModelName);
            }
            str.AppendLine("\t{");
            this._body.Params.ForEach(a =>
            {
                if (a.CheckIsWrite())
                {
                    Helper.Helper.WriteShow(a, str);
                    a.WriteProperty(str, _Prefix);
                    str.AppendLine();
                }
            });
            str.AppendLine("\t}");
            str.AppendLine("}");
            return str.ToString();
        }

        public void SaveModel(DirectoryInfo dir)
        {
            if (this._body.IsPaging && this._body.Params.Count(a => a.ParamType == "basic") == 0)
            {
                this._ModelName = "BasicPage";
                this._Use.Add("RpcModel");
                return;
            }
            else if (!this._body.IsPaging && this._body.Params.Count(a => a.ParamType == "basic") <= 1)//控制生成UI实体的参数量
            {
                this._Use.Add("RpcHelper.Validate");
                _body.Params.ForEach(a =>
                {
                    if (a.ParamType == "basic")
                    {
                        _Use.Add(a.Type.Namespace);
                    }
                });
                return;
            }
            string text = this.CreateUi_Model();
            string path = Path.Combine(dir.FullName, string.Concat(this._service.RootName, @"\", this._ModelName, ".cs"));
            Tools.WriteText(path, text, Encoding.UTF8);
        }
    }
}
